Skip to content

✨ feat(tracker): Improve Tracker page UI/UX & add Repositories tab#658

Open
Mayank251125 wants to merge 1 commit into
GitMetricsLab:mainfrom
Mayank251125:feature/improve-tracker-ui-ux
Open

✨ feat(tracker): Improve Tracker page UI/UX & add Repositories tab#658
Mayank251125 wants to merge 1 commit into
GitMetricsLab:mainfrom
Mayank251125:feature/improve-tracker-ui-ux

Conversation

@Mayank251125
Copy link
Copy Markdown

@Mayank251125 Mayank251125 commented Jun 1, 2026

Related Issue


Description

This PR significantly improves the Tracker page UI/UX, accessibility, and overall user
experience as proposed in the linked issue. It also introduces a brand new
Repositories Tab that fetches and displays real GitHub repository data.

🎨 UI/UX Improvements

  • Redesigned search form using a responsive CSS grid layout
  • Improved spacing, padding, and visual hierarchy throughout the page
  • Consistent styling across all form controls and interactive elements
  • Enhanced dark mode aesthetics and consistency
  • Made the primary Fetch Data CTA more prominent with hover glow effect
  • Added hover, focus, and active states to all interactive elements

🚀 UX Improvements

  • Added skeleton loading rows while data is being fetched
  • Added toast notifications for loading, success, and error states
  • Meaningful empty-state messages with icons when no data is available
  • Added validation feedback and disabled state on the submit button
  • Improved filter discoverability with collapsible advanced filter panel

📊 Summary Stat Cards

  • Total Issues
  • Open Issues
  • Closed Issues
  • Pull Requests
  • Repositories (new)
  • Total Stars (new)

🗂️ New: Repositories Tab

  • Fetches real repositories via GET /users/{username}/repos using Octokit
  • Displays repos in a responsive card grid (3 cols desktop / 2 tablet / 1 mobile)
  • Each card shows: name, description, language dot, stars, forks, open issues,
    topics, license, visibility badge, fork badge, last updated (relative time)
  • Filter by programming language
  • Search by repo name or description
  • Sort by: Last updated / Stars / Forks / Open issues / Name
  • Ascending/Descending toggle
  • Hide forks toggle
  • Pagination (12 repos per page)
  • New hook: useGitHubRepos.ts

🔍 Filtering & Data Experience

  • Quick filter chips: All / Open / Closed / Merged
  • Collapsible advanced filter panel: title search, repo name, start/end date
  • Sortable table columns: Title, Repository, State, Created
  • CSV export of current filtered view
  • Result count display: "Showing N results of X total"
  • Clear filters chip when filters are active

♿ Accessibility

  • aria-label on all inputs, buttons, icons, and interactive elements
  • role="tab" and aria-selected on tab pills
  • role="status" on stat cards and empty states
  • Visible :focus-visible rings on every interactive element
  • Full keyboard navigation support (Enter/Space on tabs)
  • Screen reader compatible status icons wrapped in <span role="img">

📱 Responsiveness

  • Search form stacks vertically on mobile
  • Stat cards wrap and resize on small screens
  • Table has maxWidth breakpoints per column
  • Repo card grid collapses from 3 → 2 → 1 column on smaller viewports
  • Filter panel uses responsive grid: 4 cols → 2 → 1

How Has This Been Tested?

  • ✅ Tested on Chrome, Edge (Windows)
  • ✅ Tested with valid GitHub username (torvalds, Mayank251125)
  • ✅ Tested with and without a Personal Access Token
  • ✅ Tested with invalid username (error state shown correctly)
  • ✅ Tested all 3 tabs: Issues, Pull Requests, Repositories
  • ✅ Tested all filter chips (All / Open / Closed / Merged)
  • ✅ Tested advanced filters (title, repo, date range)
  • ✅ Tested CSV export — file downloads correctly
  • ✅ Tested sort on all 4 table columns (asc + desc)
  • ✅ Tested dark mode and light mode
  • ✅ Tested mobile view (375px) and tablet (768px)
  • ✅ Tested keyboard navigation (Tab, Enter, Space)
  • npm run dev runs without errors

Screenshots (if applicable)

Screenshot 2026-06-01 103914 Screenshot 2026-06-01 103948 Screenshot 2026-06-01 103957

Type of Change

  • Bug fix
  • New feature
  • Code style update
  • Breaking change
  • Documentation update

Summary by CodeRabbit

Release Notes

  • New Features
    • Added GitHub repository tracking to the Tracker page, complementing issue/PR tracking
    • Filter repositories by language and fork status
    • Search repositories and sort by multiple fields
    • View comprehensive repository metadata including description, topics, stars, and forks
    • Paginated browsing for large repository collections

@netlify
Copy link
Copy Markdown

netlify Bot commented Jun 1, 2026

Deploy Preview for github-spy ready!

Name Link
🔨 Latest commit cb88c9c
🔍 Latest deploy log https://app.netlify.com/projects/github-spy/deploys/6a1d14898e4db20008551f3c
😎 Deploy Preview https://deploy-preview-658--github-spy.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds comprehensive GitHub repository tracking to the Tracker page. A new useGitHubRepos hook handles paginated repository fetching with error normalization, while the Tracker component is extended with repository UI components, utilities, and state management to display repos in a dedicated tab alongside issues/PRs.

Changes

Repository Tracking Feature

Layer / File(s) Summary
Repository data contract and hook implementation
src/hooks/useGitHubRepos.ts
GitHubRepo interface and useGitHubRepos hook manage paginated repository data, compute totals from link headers, and map HTTP error codes (403, 404, 401) to user-facing messages.
Tracker imports and repository utilities
src/pages/Tracker/Tracker.tsx
Module imports expanded with octicons and useGitHubRepos; new type aliases, pagination constants, language color map, and helper functions for date/time formatting, number compaction, CSV export, and repository naming.
Repository UI components
src/pages/Tracker/Tracker.tsx
RepoCard displays fork/private indicators, description, topics, language, stars/forks/issues, and updated time; ReposSection provides search, language filter, fork toggle, sortable columns, computed totals, skeleton/error/empty states, and pagination.
Tracker component state and data fetching
src/pages/Tracker/Tracker.tsx
Tracker adds repoPage state and "repos" tab option; useEffect re-fetches repositories on page changes; submit handler triggers issues/PRs and repositories fetch concurrently via toast.promise.
Tracker render flow with repository tab support
src/pages/Tracker/Tracker.tsx
Render flow now includes repository summary cards, Repositories tab label, conditional filtering UI hiding for repos mode, ReposSection rendering for tab === "repos", and updated issues/PR table controls using shared sort helpers.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • GitMetricsLab/github_tracker#517: Both PRs modify src/pages/Tracker/Tracker.tsx's data-fetching flow to use effect-driven auto-triggered fetches and update how username/pagination changes initiate data retrieval.
  • GitMetricsLab/github_tracker#238: The retrieved PR updates useGitHubAuth and useGitHubData error handling for unauthenticated Octokit usage, directly supporting this PR's new useGitHubRepos(getOctokit) hook and error normalization patterns.
  • GitMetricsLab/github_tracker#515: Both PRs implement GitHub repository tracking by adding a repository-focused hook and wiring it into src/pages/Tracker/Tracker.tsx with repository state and UI components.

Suggested labels

level:advanced, type:feature, type:accessibility, quality:clean

Poem

🐰 A tracker now hops with repository might,
Repos dance alongside issues in the light,
Paginated fetches and cards oh so neat,
With search and with sorting, the tracker's complete! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly summarizes the main change: improved Tracker page UI/UX with a new Repositories tab, matching the core objectives.
Description check ✅ Passed Description comprehensively covers all required sections: Related Issue (#606), detailed Description of improvements, How tested, Screenshots, and Type of Change selection.
Linked Issues check ✅ Passed PR successfully implements all key coding objectives from #606: UI/UX improvements, accessibility enhancements, responsive design, filtering/sorting features, summary stat cards, Repositories tab with real GitHub data fetch via new useGitHubRepos hook, CSV export, and skeleton loading/empty states.
Out of Scope Changes check ✅ Passed All changes are scoped to #606 objectives: new useGitHubRepos hook, Tracker component refactor with repos tab, RepoCard and ReposSection components, and related UI/UX improvements are all directly required by the issue.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 Thank you @Mayank251125 for your contribution. Please make sure your PR follows https://github.com/GitMetricsLab/github_tracker/blob/main/CONTRIBUTING.md#-pull-request-guidelines

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/hooks/useGitHubRepos.ts`:
- Around line 57-68: The catch block in useGitHubRepos.ts swallowing errors
(inside fetchRepos) only calls setError and lets the promise resolve, so callers
like Tracker.tsx's handleSubmit (which uses toast.promise) incorrectly show
success; after each setError branch in the catch, propagate the failure by
re-throwing the original error (or return Promise.reject(err)) so fetchRepos
rejects and the caller can surface the correct toast/result—update the catch in
fetchRepos to throw err (or reject) after setError.
- Around line 49-56: The code incorrectly computes totalRepos by always
multiplying the rel="last" page number by perPage; change the logic in
useGitHubRepos to parse last page via lastMatch (keep linkHeader, lastMatch,
perPage, page, response.data.length, setTotalRepos) and compute total as
(lastPage - 1) * perPage + itemsOnLastPage, where itemsOnLastPage should be
response.data.length when the current page is the last page (lastPage === page)
and perPage otherwise; if you need exact totals even when the current page is
not the last, perform an extra fetch for the last page to read its length and
then setTotalRepos accordingly.

In `@src/pages/Tracker/Tracker.tsx`:
- Around line 615-626: The pagination effects currently read the mutable
`username` input, causing refetches to use unsaved edits; create and use a
committed `submittedUsername` state set by the search submit handler, then
change both effects (the tab/page effect that calls `fetchData` and the repoPage
effect that calls `fetchRepos`, and any other related effects around the 628-649
region) to read `submittedUsername` instead of `username` and include
`submittedUsername` in their dependency arrays; ensure the submit handler
assigns the current input to `submittedUsername` so all follow-up fetches
consistently use the last submitted username.
- Around line 428-442: The current filtering/sorting logic uses the paginated
array "repos" so search/filters (in the block producing "filtered") only run
against the current page; move the filtering/sorting to operate on the full
repository set (or fetch/cache all repos) before pagination is applied: ensure
the filter conditions referencing showForks, langFilter, search and the sort
logic using sort and sortDir are executed against the complete collection (e.g.,
"allRepos" or the fetched master list) and only then slice for the page, or
alternatively perform server-side filtering so the paginated "repos" is already
the filtered result.
- Around line 877-883: The tab elements rendered with Box currently only set
tabIndex on the active tab and handle Enter/Space but lack ArrowLeft/ArrowRight
roving focus; update the Tab keyboard handler to support left/right arrow
navigation by moving focus to the previous/next tab and calling setTab(newKey)
(wrapping at ends), and ensure tabIndex is 0 for the newly focused tab and -1
for others so focus moves correctly; modify the onKeyDown for the Box (and the
container with role="tablist" if present) to handle e.key ===
"ArrowRight"/"ArrowLeft" (and optionally Home/End) and also reset page/state via
setPage(0)/setStateFilter("all") when changing tabs to match existing click
behavior.
- Around line 444-455: The UI is showing page-only aggregates (totalStars,
totalForks computed from repos) but labels them as overall totals; update the
logic in Tracker.tsx so the summary uses the true overall totals or clearly
labels them as "this page": either (A) replace totalStars/totalForks with the
global totals source (if you have a backend/parent value like
totalStarsAll/totalForksAll or a paginatedTotals object) and use those in the
labels passed to fmtNum, or (B) change the label strings where
totalStars/totalForks (and the same occurrences around symbols at lines ~681-683
and ~855-863) are used to say "this page" (e.g., "stars on this page") so they
accurately reflect repos (the current page) rather than the entire dataset;
update every usage of totalStars and totalForks in Tracker.tsx accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1f1699d0-178f-4270-8ff6-0ca376a08974

📥 Commits

Reviewing files that changed from the base of the PR and between 53f820b and cb88c9c.

📒 Files selected for processing (2)
  • src/hooks/useGitHubRepos.ts
  • src/pages/Tracker/Tracker.tsx

Comment on lines +40 to +47
const response = await octokit.request('GET /users/{username}/repos', {
username,
per_page: perPage,
page,
sort: 'pushed',
direction: 'desc',
type: 'owner',
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the hook implementation around the referenced lines
sed -n '1,200p' src/hooks/useGitHubRepos.ts

# Inspect Tracker usage for toast.promise contract
sed -n '1,240p' src/pages/Tracker/Tracker.tsx

Repository: GitMetricsLab/github_tracker

Length of output: 9576


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate toast.promise / handleSubmit usage in Tracker.tsx
rg -n "toast\.promise|handleSubmit|Promise\.all\(\[|fetchRepos\(" src/pages/Tracker/Tracker.tsx

# Print the relevant region around handleSubmit/toast.promise (limit output)
sed -n '1,260p' src/pages/Tracker/Tracker.tsx
sed -n '260,560p' src/pages/Tracker/Tracker.tsx
sed -n '560,920p' src/pages/Tracker/Tracker.tsx

Repository: GitMetricsLab/github_tracker

Length of output: 37926


🌐 Web query:

GitHub REST API GET /users/{username}/repos private repositories authenticated visibility=all include private

💡 Result:

GitHub REST API does not support the exact endpoint/parameters in your query. 1) Endpoint mismatch - GET /users/{username}/repos is the endpoint for listing repositories for a specified user, but the REST API docs describe a limited set of query parameters (not a visibility=all style “include private” for that endpoint) and it’s not the authenticated-user listing endpoint. [1] 2) Correct endpoint for “include private” - To list both public and private repositories, you should use the “list repositories for the authenticated user” endpoint: GET /user/repos. [1] - That endpoint supports a visibility query parameter with allowed values all, public, private; default is all. [1] - Therefore, to include private repos, use visibility=private (or visibility=all) together with authentication. [1] 3) Authentication/scope requirement - Private repositories are returned only if the authenticated token/app has sufficient OAuth scope/permissions; generally GitHub requires appropriate repo/user permissions for private data. A related users endpoint notes that OAuth tokens need the repo scope to include private information. [2] Practical example (REST): - GET https://api.github.com/user/repos?visibility=all - Authorization: Bearer (must be authorized to access the private repos) [1][2] If you tell me whether you’re using a Personal Access Token, GitHub App installation token, or OAuth app token (and which scopes/permissions you have), I can recommend the exact visibility/affiliation/type filters and the right auth headers.

Citations:


Fix repo fetching: private-repo endpoint, pagination count, and toast success/error contract

  • useGitHubRepos requests GET /users/{username}/repos (with type: 'owner'), which won’t include private repositories even with a PAT; switch to the authenticated-user endpoint (GET /user/repos) and pass visibility=all|private (with proper token scopes).
    const response = await octokit.request('GET /users/{username}/repos', {
      username,
      per_page: perPage,
      page,
      sort: 'pushed',
      direction: 'desc',
      type: 'owner',
    });
  • totalRepos multiplies the rel="last" page number by perPage, which overestimates when the last page is partial.
  • fetchRepos swallows errors (sets error state but never rethrows), so Tracker.tsx’s toast.promise(Promise.all([p1, p2])) can show the success message even when repos fail to load; make fetchRepos reject on failure (or change toast to use reposError).

Comment on lines +49 to +56
const linkHeader = (response.headers as any)?.link ?? '';
const lastMatch = linkHeader.match(/page=(\d+)>; rel="last"/);
const total = lastMatch
? parseInt(lastMatch[1], 10) * perPage
: (page - 1) * perPage + response.data.length;

setRepos(response.data as GitHubRepo[]);
setTotalRepos(total);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

totalRepos is wrong when the last page is not full.

Multiplying rel="last" by perPage overcounts for any user whose final page has fewer than perPage repositories. A user with 13 repos and perPage=12 will be reported as 24 here, which then breaks the repo stat card and pagination bounds.

🧰 Tools
🪛 ESLint

[error] 49-49: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/hooks/useGitHubRepos.ts` around lines 49 - 56, The code incorrectly
computes totalRepos by always multiplying the rel="last" page number by perPage;
change the logic in useGitHubRepos to parse last page via lastMatch (keep
linkHeader, lastMatch, perPage, page, response.data.length, setTotalRepos) and
compute total as (lastPage - 1) * perPage + itemsOnLastPage, where
itemsOnLastPage should be response.data.length when the current page is the last
page (lastPage === page) and perPage otherwise; if you need exact totals even
when the current page is not the last, perform an extra fetch for the last page
to read its length and then setTotalRepos accordingly.

Comment on lines +57 to +68
} catch (err: any) {
const status = err?.status;
const message = err?.message?.toLowerCase() ?? '';

if (status === 403) {
setError('GitHub API rate limit exceeded. Please provide a PAT to continue.');
} else if (status === 404 || message.includes('not found')) {
setError('User not found. Please check the GitHub username.');
} else if (status === 401) {
setError('Invalid token. Please check your Personal Access Token.');
} else {
setError('Unable to fetch repositories. Please verify the username or network connection.');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Propagate repo fetch failures back to the caller.

This catch path only updates local state, so fetchRepos still resolves successfully. In Tracker.tsx, handleSubmit wraps it in toast.promise, which means a repo-only failure still produces the success toast. Re-throw after setError(...) or return an explicit failure result so the caller can surface the right outcome.

🧰 Tools
🪛 ESLint

[error] 57-57: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/hooks/useGitHubRepos.ts` around lines 57 - 68, The catch block in
useGitHubRepos.ts swallowing errors (inside fetchRepos) only calls setError and
lets the promise resolve, so callers like Tracker.tsx's handleSubmit (which uses
toast.promise) incorrectly show success; after each setError branch in the
catch, propagate the failure by re-throwing the original error (or return
Promise.reject(err)) so fetchRepos rejects and the caller can surface the
correct toast/result—update the catch in fetchRepos to throw err (or reject)
after setError.

Comment on lines +428 to +442
const filtered = repos
.filter((r) => {
if (!showForks && r.fork) return false;
if (langFilter !== "All" && r.language !== langFilter) return false;
if (search &&
!r.name.toLowerCase().includes(search.toLowerCase()) &&
!(r.description ?? "").toLowerCase().includes(search.toLowerCase())) return false;
return true;
})
.sort((a, b) => {
const av = (a as any)[sort] ?? 0;
const bv = (b as any)[sort] ?? 0;
const cmp = typeof av === "string" ? av.localeCompare(bv) : av < bv ? -1 : av > bv ? 1 : 0;
return sortDir === "asc" ? cmp : -cmp;
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Repo search/filter/sort only works on the current page slice.

These controls run against the 12 repositories currently loaded into repos, not the user's full repository set. Once a user has multiple pages, searching or filtering can show "No repositories found" even when matching repos exist on later pages. This needs either all-repos fetching/caching or server-side filtering before exposing global search/filter UI.

🧰 Tools
🪛 ESLint

[error] 438-438: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 439-439: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/Tracker/Tracker.tsx` around lines 428 - 442, The current
filtering/sorting logic uses the paginated array "repos" so search/filters (in
the block producing "filtered") only run against the current page; move the
filtering/sorting to operate on the full repository set (or fetch/cache all
repos) before pagination is applied: ensure the filter conditions referencing
showForks, langFilter, search and the sort logic using sort and sortDir are
executed against the complete collection (e.g., "allRepos" or the fetched master
list) and only then slice for the page, or alternatively perform server-side
filtering so the paginated "repos" is already the filtered result.

Comment on lines +444 to +455
const totalStars = repos.reduce((s, r) => s + r.stargazers_count, 0);
const totalForks = repos.reduce((s, r) => s + r.forks_count, 0);

return (
<Box>
{/* Mini stat row */}
{!loading && repos.length > 0 && (
<Box sx={{ display: "flex", gap: 3, mb: 2.5, flexWrap: "wrap" }}>
{[
{ icon: <BookOpen size={14} />, label: `${totalRepos} repositories` },
{ icon: <Star size={14} />, label: `${fmtNum(totalStars)} stars total` },
{ icon: <GitFork size={14} />, label: `${fmtNum(totalForks)} forks total` },
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

These "total" repo metrics are page totals.

totalStars and totalForks are reduced from the current repos page, but the UI labels them as overall totals in both the repos header and the summary cards. For users with more than one repo page, those numbers are incorrect. Either aggregate across the full dataset or relabel them as "this page".

Also applies to: 681-683, 855-863

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/Tracker/Tracker.tsx` around lines 444 - 455, The UI is showing
page-only aggregates (totalStars, totalForks computed from repos) but labels
them as overall totals; update the logic in Tracker.tsx so the summary uses the
true overall totals or clearly labels them as "this page": either (A) replace
totalStars/totalForks with the global totals source (if you have a
backend/parent value like totalStarsAll/totalForksAll or a paginatedTotals
object) and use those in the labels passed to fmtNum, or (B) change the label
strings where totalStars/totalForks (and the same occurrences around symbols at
lines ~681-683 and ~855-863) are used to say "this page" (e.g., "stars on this
page") so they accurately reflect repos (the current page) rather than the
entire dataset; update every usage of totalStars and totalForks in Tracker.tsx
accordingly.

Comment on lines 615 to +626
useEffect(() => {
if (username) {
if (prevFetched.current && username && tab !== "repos") {
fetchData(username, page + 1, ROWS_PER_PAGE);
}
}, [tab, page]);

const handleSubmit = (e: React.FormEvent<HTMLFormElement>): void => {
e.preventDefault();
setPage(0);
fetchData(username, 1, ROWS_PER_PAGE);
};
}, [tab, page]); // eslint-disable-line react-hooks/exhaustive-deps

const handlePageChange = (_: unknown, newPage: number) => {
setPage(newPage);
};

const formatDate = (dateString: string): string =>
new Date(dateString).toLocaleDateString();
// NEW: re-fetch repos on repoPage change
useEffect(() => {
if (prevFetched.current && username && tab === "repos") {
fetchRepos(username, repoPage + 1, REPOS_PER_PAGE);
}
}, [repoPage]); // eslint-disable-line react-hooks/exhaustive-deps
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Pagination is tied to the editable input, not the last submitted username.

After a successful search, the user can change the username field without submitting. The next page/tab refetch will then use that unsaved value, so pagination can silently switch accounts while the rest of the screen still reflects the previous search. Store a committed submittedUsername on submit and drive all follow-up fetches from that value.

Also applies to: 628-649

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/Tracker/Tracker.tsx` around lines 615 - 626, The pagination effects
currently read the mutable `username` input, causing refetches to use unsaved
edits; create and use a committed `submittedUsername` state set by the search
submit handler, then change both effects (the tab/page effect that calls
`fetchData` and the repoPage effect that calls `fetchRepos`, and any other
related effects around the 628-649 region) to read `submittedUsername` instead
of `username` and include `submittedUsername` in their dependency arrays; ensure
the submit handler assigns the current input to `submittedUsername` so all
follow-up fetches consistently use the last submitted username.

Comment thread src/pages/Tracker/Tracker.tsx
@Mayank251125 Mayank251125 reopened this Jun 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🚀 Feature: Improve Tracker Page UI/UX, Accessibility, Filtering Experience & Contributor-Friendly Enhancements for GSSoC'26

1 participant